using System.Collections.Concurrent;

namespace Pinwheel.Kernel
{
    public class WorkProcess : TaskScheduler, IWorkerProcess
    {
        private ServiceManager m_ServiceManager;
        public ServiceManager ServiceManager => m_ServiceManager;

        private bool m_IsRunning = false;
        public bool IsRunning => m_IsRunning;
        
        private int m_index;
        
        private int m_CoreId;
        public int CoreId => m_CoreId;
        
        private Thread m_ProcessThread;   // 绑定的物理核心线程
        public Thread ProcessThread => m_ProcessThread;
        
        private TaskFactory m_TaskFactory;
        public TaskFactory TaskFactory => m_TaskFactory;

        private MessageQueue m_MessageQueue;
        internal MessageQueue MessageQueue => m_MessageQueue;
        
        
        private ConcurrentQueue<Task> m_TaskQueue;
        

        public WorkProcess(ServiceManager serviceManager, int coreId)
        {
            var coreCount = SystemInfo.GetPhysicalCoreCount();
            m_ServiceManager = serviceManager;
            m_index = coreId;
            m_CoreId = coreId % coreCount;
            m_TaskQueue = new ConcurrentQueue<Task>();
            m_TaskFactory = new TaskFactory(this);
        }
        
        // 启动线程并绑定到核心
        public void Start()
        {
            m_IsRunning = true;
            m_ProcessThread = new Thread(ThreadLoop);
            m_ProcessThread.IsBackground = true;
            m_ProcessThread.Start();
        }
        
        // 线程的主循环
        private void ThreadLoop()
        {
            // 绑定线程到指定的物理核心
            ProcessAffinity.SetAffinity(CoreId);
            Log.Info($"WorkProcess {CoreId} started. ThreadId: {Thread.CurrentThread.ManagedThreadId}");
            while (m_IsRunning || (null != m_TaskQueue && m_TaskQueue.Count > 0))
            {
                if (!ExecuteTask() && Update() > 0)
                {
                    // 如果没有任务执行，可以选择休眠一段时间，减少CPU占用
                    Thread.Sleep(1);
                }
            }
        }
        
        // 工作线程更新
        private int Update()
        {
            // 没有任何消息需要处理
            if (null! == m_MessageQueue || m_MessageQueue.Count == 0)
            {
                if (!Global.MessageQueues.TryDequeue(out m_MessageQueue))
                {
                    // MessageQueue cooperation = null!;
                    // for (int i = 0; i < ServiceManager.WorkProcesses.Length; i++)
                    // {
                    //     if (i == m_index) continue;
                    //     var worker = ServiceManager.WorkProcesses[i];
                    //     if (null! == worker.MessageQueue) continue;
                    //     if (worker.MessageQueue.Count < 10) continue;
                    //     cooperation = worker.MessageQueue;
                    //     break;
                    // }
                    //
                    // if (null! != cooperation && cooperation.Count > 0)
                    // {
                    //     m_TaskFactory.StartNew(cooperation.DispatchAsync);
                    //     return 0;
                    // }
                    return 1;
                }
            }
            
            // 处理消息队列中的消息
            // TODO: 没做超时处理和取消的处理
            m_TaskFactory.StartNew(m_MessageQueue.DispatchAsync);
            
            // if (m_MessageQueue.State > 0)
            // {
            //     Global.MessageQueues.Enqueue(m_MessageQueue);
            //     m_MessageQueue = null!;
            // }
            
            return 0;
        }
        
        // 从队列中取任务并执行
        private bool ExecuteTask()
        {
            if (!m_TaskQueue.TryDequeue(out var task)) return false;
            try
            {
                if (!TryExecuteTask(task))
                {
                    // 如果任务未能立即执行，可以选择重新排队或者进行其他错误处理
                    m_TaskQueue.Enqueue(task);
                }
            }
            catch (Exception ex)
            {
                // 处理任务执行过程中的异常，比如记录日志、采取恢复措施等
                // Log.Error($"Task execution failed: {ex.Message}");
                Log.Exception(ex);
                throw;
            }
            return true;
        }

        public void Send(PID pid, string method, MessageType type, IMessage message)
        {
            m_ServiceManager.Send(PID.System, pid, method, type, message);
        }

        // 获取当前所有排队的任务
        protected override IEnumerable<Task> GetScheduledTasks()
        {
            return m_TaskQueue.ToArray();
        }

        // 将任务排队到任务队列
        protected override void QueueTask(Task task)
        {
            if (m_IsRunning && null! != m_TaskQueue)
            {
                m_TaskQueue.Enqueue(task);
            }
        }

        // 允许任务仅在当前线程为工作线程时内联执行
        protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
        {
            if (Thread.CurrentThread == ProcessThread)
            {
                if (!taskWasPreviouslyQueued || TryDequeue(task))
                {
                    return TryExecuteTask(task);
                }
            }
            return false;
        }

        // 停止工作线程
        public void Stop()
        {
            m_IsRunning = false;

            // 等待线程安全退出
            if (m_ProcessThread != null! && m_ProcessThread.IsAlive)
            {
                m_ProcessThread.Join();  // 等待线程完全退出
            }
        }
    }
}